/**************************************************************/
/*                                                            */
/*     MC823 - Laboratorio de Teleprocessamento e Redes       */
/*     1 Semestre / 2013                                      */
/*     Projeto 1 - Cliente e Servidor RMI de uma Livraria     */
/*                                                            */
/*     Alunos: Joao Gabriel M.D.Mendes - RA 102788            */
/*             Lucas Domingues Lima    - RA 103140            */
/*                                                            */
/**************************************************************/

/* Arquivo: livraria/rmi/src/Server.java
   Definicao: Classe Server, implementando as funcoes disponibi-
   			  lizadas na interface Livraria, que e invocada
   			  remotamente. Contem o estoque em si, e a cada
   			  requisicao, marca o tempo e registra tudo num log.
   			  Para rodar: java livraria/rmi/Server
*/


package livraria.rmi;
	
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.lang.System;
import java.io.*;
	
public class Server implements Livraria {

	private static int NANOPERSEC = 1000000000;
	
	private t_estoque estoque;
	
	//construtor inicializa estoque
    public Server() {
    	this.estoque = new t_estoque();
    }
    
    //funcoes correspondentes as requisicoes do cliente. Na classe 
    //Server, apenas tomada de tempo e escrita em log sao feitas.
    //As requisicoes estao implementadas de fato na classe t_estoque.
    
    public String retornaTitulosISBN(String user_id) {
    	try {
			long t_start = System.nanoTime();
			
			String response = estoque.retornaTitulosISBN();
			
			//log writing...
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: retornaTitulosISBN";
			logwriter.println(String.format(request,user_id));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("0 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
    }
    
    public String retornaInfoEstoque(String user_id) {
    	try {
			long t_start = System.nanoTime();
			
			String response = estoque.retornaInfoEstoque();
			
			//log writing...
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: retornaInfoEstoque";
			logwriter.println(String.format(request,user_id));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("1 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
    }
    
    public String retornaDescricao(String user_id, String ISBN) {
    	try {
			long t_start = System.nanoTime();
			
			String response = estoque.retornaDescricao(ISBN);
			
			//log writing...
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: retornaDescricao %s";
			logwriter.println(String.format(request,user_id,ISBN));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("2 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
    }
    
    public String retornaInfoLivro(String user_id, String ISBN) {
    	try {
			long t_start = System.nanoTime();
			
			String response = estoque.retornaInfoLivro(ISBN);
			
			//log writing
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: retornaInfoLivro %s";		
			logwriter.println(String.format(request,user_id,ISBN));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("3 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
    }
    
	public String retornaNumLivro(String user_id, String ISBN) {
		try {
			long t_start = System.nanoTime();

			String response = estoque.retornaNumLivro(ISBN);
			
			//log writing
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: retornaNumLivro %s";
			logwriter.println(String.format(request,user_id,ISBN));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("4 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
	} 
	
	
	//Verifica se user_id inicia com 'l', de livraria. Se sim, entao
	//usuario e do tipo livraria e funcao de alteracao de estoque e
	//executada no estoque. Se nao, apenas uma mensagem de erro
	//e gerada.
	public String alteraEstoque(String user_id, String ISBN, int num) {
		try {
			long t_start = System.nanoTime();
			String response = "";
			
			if(user_id.startsWith("l")) {
				response = estoque.alteraEstoque(ISBN, num);
			} else { response = "Operacao nao permitida."; }
			
			//log writing...
			PrintWriter logwriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".log", true)));
			PrintWriter twriter = new PrintWriter(new BufferedWriter(new FileWriter("server_"+user_id+".time", true)));
			String request = "User %s requested: alteraEstoque %s %d";
			logwriter.println(String.format(request,user_id,ISBN,num));
			logwriter.println(response);
			logwriter.close();
			double t_spent = (double)(System.nanoTime() - t_start)/NANOPERSEC;
			String time = String.format("5 %.9f",t_spent);
			twriter.println(time);
			twriter.close();
			return response;
		} catch (Exception e) {
			System.err.println("Client exception: " + e.toString());
			e.printStackTrace();
		}
		return "Erro inesperado!";
	}
    	
    public static void main(String args[]) {
	
	try {
		//initialize Server object
	    Server obj = new Server();
	    Livraria stub = (Livraria) UnicastRemoteObject.exportObject(obj, 0);

	    // Bind the remote object's stub in the registry
	    Registry registry = LocateRegistry.getRegistry();
	    registry.bind("Livraria", stub);

	    System.err.println("Server ready");
	} catch (Exception e) {
	    System.err.println("Server exception: " + e.toString());
	    e.printStackTrace();
	}
    }
}
